# -*- coding: utf-8 -*-
"""
Created on Sun Oct  3 10:55:21 2021

@author: 刘长奇-2019300677
"""
import matplotlib.pyplot as plt 
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import numpy as np
from sklearn.metrics import confusion_matrix
import seaborn as sns
# load data
digits = load_digits()

# copied from notebook 02_sklearn_data.ipynb
fig = plt.figure(figsize=(6, 6))  # figure size in inches
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)

pca = PCA(n_components=2, svd_solver="randomized")
proj = pca.fit_transform(digits.data)


#定义逻辑回归函数
#定义逻辑回归函数
def sigmoid(x):
    #防止越界，分正负讨论
    if x>0:
        return 1.0 / (1 + np.exp(-x))
    else:
        return np.exp(x)/(np.exp(x)+1)


#定义线性拟合函数
def lmodel(a,b,x):
    return a*x+b

#梯度下降的最大似然估计
def grad_down(train,y,a,b,theta):
    N=np.shape(train)[0]
    
   
    for i in range(700):
        for j in range(N):
            a=a-((sigmoid(lmodel(a,b,proj[j][0]))-y[j])*proj[j][0])*theta
            b=b-theta*((sigmoid(lmodel(a,b,proj[j][0]))-y[j]))
    return a,b

theta= 0.0001             #学习率
y=[]
a=np.zeros(10)
b=np.zeros(10)
N=np.shape(proj)[0] 

for i in range(10):
    for j in range(N):
        if digits.target[j]==i:
            y.append(1)
        else:
            y.append(0)
    a[i],b[i]=grad_down(proj,y,a[i],b[i],theta)
    y=[]
label=np.zeros(N)
#贴标签
for j in range(N):
    temp=[]
    for i in range (10):
        temp.append(sigmoid(lmodel(a[i],b[i],proj[j][0])))
    temp=np.array(temp)
    
    label[j]=np.argmax(temp)
i=0
for j in range(N):
    if label[j]==digits.target[j]:
        i=i+1
    if j==N-1:
        print('准确率为：',i/N)
        
#绘制混淆矩阵的图像，将数据分类结果正误情况可视化
confusion_matrix_result=confusion_matrix(label,digits.target)
plt.figure(figsize=(10,6))
sns.heatmap(confusion_matrix_result,annot=True,cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()